﻿using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;

namespace Wen.GrpcService.Helps;

public class AesRsaHelp
{
    public static string RsaFromPem { get; set; } = @"-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxot7LoZAVHZDhlGE8e6/
WqTmgmGZhVepofQhhynB/jTA69lMXoKfcXJMr/8Zyfdug97re7NkJX8Jei4cJlEv
nyzNRrY1tz1+dkrISYi0nBkwaDMTd2Wsw63QjcqZl1yCTVT6jboNR/0a7hyb2gwt
5cXW2ylgVZ6PttOUPXb3ZF8oWLe1BVWfcQXFIlErqVjsY3iFgcNxCucvYhiDzcbm
qHFIbUj9760E666Ws3Io32OQK1EkkdufqNuL1gm9/9qYXE0KChGzetnFfhtOGmvK
cPp3os07zdeeFOdKbwCbZjUxSy2a/6IKvEWilONNPNSMBxcc70oci565CtrIdyah
IQIDAQAB
-----END PUBLIC KEY-----";

    public static string AesKey = "u4GP+xHwd3slNDYCVeOvDpbe0eLJz7XpaEj46SA9EtM=";
    public static string AesIv = "8Daxh29YSAjUBulFYoMhdw==";

    /// <summary>
    /// 获取 Salt值
    /// </summary>
    /// <param name="length"></param>
    /// <returns></returns>
    public static string GenerateSalt(int length = 36)
    {
        var randomNumberGenerator = RandomNumberGenerator.Create();
        byte[] array = new byte[length];
        randomNumberGenerator.GetBytes(array);
        return Convert.ToBase64String(array);
    }

    /// <summary>
    /// 获取Hash 值
    /// </summary>
    /// <param name="data"></param>
    /// <param name="salt"></param>
    /// <returns></returns>
    public static string ComputeHash(string data, string salt)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(data + salt);
        return Convert.ToBase64String(SHA256.HashData(bytes));
    }

    /// <summary>
    /// RSA签名（实际为签名操作）
    /// </summary>
    /// <param name="data"></param>
    /// <param name="privateKeyXml"></param>
    /// <returns></returns>
    public static string SignData(string data, string privateKeyXml)
    {
        using var rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(privateKeyXml);
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);
        byte[] signature = rsa.SignData(dataBytes, SHA256.Create());
        return Convert.ToBase64String(signature);
    }

    /// <summary>
    /// 验证签名
    /// </summary>
    /// <param name="data"></param>
    /// <param name="signature"></param>
    /// <returns></returns>
    public static bool VerifyData(string data, string signature)
    {
        using var rsa = RSA.Create(2048);
        rsa.ImportFromPem(RsaFromPem);
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);
        byte[] signatureBytes = Convert.FromBase64String(signature);
        return rsa.VerifyData(dataBytes, signatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
    }

    /// <summary>
    /// 解密
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static string Decrypt(string text)
    {
        using var aes = Aes.Create();
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        aes.Key = Convert.FromBase64String(AesKey);
        aes.IV = Convert.FromBase64String(AesIv);
        var decryptor = aes.CreateDecryptor();
        byte[] cipherBytes = Convert.FromBase64String(text);
        using var ms = new MemoryStream(cipherBytes);
        using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
        using var sr = new StreamReader(cs);
        return sr.ReadToEnd();
    }
    /// <summary>
    /// 加密
    /// </summary>
    /// <param name="text"></param>
    /// <returns></returns>
    public static string Encrypt(string text)
    {
        using var aes = Aes.Create();
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.PKCS7;
        aes.Key = Convert.FromBase64String(AesKey);
        aes.IV = Convert.FromBase64String(AesIv);
        var encryptor = aes.CreateEncryptor();

        using var ms = new MemoryStream();
        using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
        {
            byte[] plainBytes = Encoding.UTF8.GetBytes(text);
            cs.Write(plainBytes, 0, plainBytes.Length);
        }
        return Convert.ToBase64String(ms.ToArray());
    }
}
